home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / misc1 / iv26_w30.zip / SOURCES / WPAINT.C < prev    next >
C/C++ Source or Header  |  1992-03-18  |  15KB  |  667 lines

  1. /*
  2.  *  MS Windows - dependent code
  3.  */
  4.  
  5. #include <Interviews\bitmap.h>
  6. #include <Interviews\paint.h>
  7. #include <Interviews\defs.h>
  8. #include <Interviews\X11\worldrep.h>
  9. #include <InterViews\X11\palette.h>
  10. #include <ctype.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <dir.h>
  14. #include <stdio.h>
  15. #include <fstream.h>
  16.  
  17. char* Stock_Fonts[] = { { "ANSI_FIXED_FONT" },
  18.             { "ANSI_VAR_FONT" },
  19.             { "DEVICE_DEFAULT_FONT" },
  20.             { "OEM_FIXED_FONT" },
  21.             { "SYSTEM_FONT" } };
  22.  
  23. /*
  24.  ********************  class Brush  *************************
  25.  */
  26.  
  27. BrushRep::BrushRep (int* pattern, int c, int width) {
  28.     count = c;
  29.     if (c != 0) {
  30.     info = new int[count];
  31.     for (int i = 0; i < count; ++i) {
  32.         *(info + i) = pattern[i];
  33.     }
  34.     }
  35. }
  36.  
  37. BrushRep::~BrushRep () {
  38.     if ((info != nil) && (count != 0)) {
  39.     delete info;
  40.     }
  41. }
  42.  
  43. /*
  44.  **************************  class Color  *********************************
  45.  */
  46.  
  47. boolean ColorRep::ScanColorFile (
  48.     const char* name, ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
  49. ) {
  50.     char *file, *ptr;
  51.     char color[30];
  52.     char buf[50];
  53.     FILE* source;
  54.     boolean result = false;
  55.  
  56.     r = 0; g = 0; b = 0;
  57.     if ((file = searchpath("colors.ali")) == 0) {
  58.     return result;
  59.     }
  60.     source = fopen(file, "r");
  61.  
  62. /*
  63.  * Der Farbstring wird in einen String, wie ihn "colors.ali" verwendet,
  64.  * umgwandelt.
  65.  */
  66.  
  67.     for (int j = 0, i = 0; i < strlen(name); i++) {
  68.     if (name[i] != ' ') {
  69.         color[j++] = tolower(name[i]);
  70.     }
  71.     }
  72.     color[j] = ' ';
  73.     color[j+1] = '\0';
  74.  
  75. /*
  76.  * "Colors.ali" wird auf Vorhandensein des Strings überprüft.
  77.  * Erfolg wird dann gemeldet, wenn der String in einer Zeile
  78.  * zu finden ist, und wenn er an der ersten Position der Zeile
  79.  * beginnt (d.h. er ist nicht Teilstring einer anderen Farbe, wie
  80.  * z.B. "blue" von "mediumblue").
  81.  */
  82.  
  83.     while (!feof(source)) {
  84.     fgets(buf, 50, source);
  85.     if ((ptr = strstr(buf, color)) != NULL && ptr == buf) {
  86.         char* tmp;
  87.         tmp = strtok(buf, " ");
  88.         tmp = strtok(NULL, " ");
  89.         r = atoi(tmp);
  90.         tmp = strtok(NULL, " ");
  91.         g = atoi(tmp);
  92.         tmp = strtok(NULL, " \n\0");
  93.         b = atoi(tmp);
  94.         result = true;
  95.         break;
  96.     }
  97.     }
  98.     fclose(source);
  99.     return result;
  100. }
  101.  
  102. inline unsigned MakeXIntensity (unsigned i) {
  103.     return ((i << 8) + i);
  104. }
  105.  
  106. inline unsigned MakeWinIntensity (unsigned i) {
  107.     return (i >> 8);
  108. }
  109.  
  110. ColorRep::ColorRep (
  111.     ColorIntensity r, ColorIntensity g, ColorIntensity b
  112. ) {
  113.     red   = MakeWinIntensity(r);
  114.     green = MakeWinIntensity(g);
  115.     blue  = MakeWinIntensity(b);
  116.     pixel = _palette->SetEntry(red, green, blue);
  117. }
  118.  
  119. ColorRep::ColorRep (
  120.     long p, ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
  121. ) {
  122.     r = GetRValue(p);
  123.     g = GetGValue(p);
  124.     b = GetBValue(p);
  125.     pixel = _palette->SetEntry(r, g, b);
  126.     red = r; green = g; blue = b;
  127.     r = MakeXIntensity(red);
  128.     g = MakeXIntensity(green);
  129.     b = MakeXIntensity(blue);
  130. }
  131.  
  132. ColorRep::ColorRep (
  133.     const char* name, ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
  134. ) {
  135.     if (ScanColorFile(name, red, green, blue)) {
  136.     pixel = _palette->SetEntry(red, green, blue);
  137.     } else {
  138.     pixel = 0;
  139.     }
  140.     r = MakeXIntensity(red);
  141.     g = MakeXIntensity(green);
  142.     b = MakeXIntensity(blue);
  143. }
  144.  
  145. ColorRep::~ColorRep () {
  146.     /*** aus Palette entfernen ***/
  147. }
  148.  
  149. int ColorRep::GetPixel () {
  150.     return pixel;
  151. }
  152.  
  153. void ColorRep::GetIntensities (
  154.      ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
  155. ) {
  156.     r = red;
  157.     g = green;
  158.     b = blue;
  159. }
  160.  
  161. /*
  162.  ******************************  class Font  ***********************
  163.  */
  164.  
  165. FontRep::FontRep () {
  166.     height = 0;
  167.     id = nil;
  168. }
  169.  
  170. FontRep::~FontRep() {
  171. }
  172.  
  173. boolean FontRep::IsStockFont (const char* f) {
  174.     char tmp[FONTSTRINGSIZE];
  175.     int stock_font = -1;
  176.  
  177.     strcpy(name, f);
  178.     strcpy(tmp, name);
  179.     if (strcmpi(tmp, Stock_Fonts[0]) == 0) {
  180.     stock_font = ANSI_FIXED_FONT;
  181.     } else if (strcmpi(tmp, Stock_Fonts[1]) == 0) {
  182.     stock_font = ANSI_VAR_FONT;
  183.     } else if (strcmpi(tmp, Stock_Fonts[2]) == 0) {
  184.     stock_font = DEVICE_DEFAULT_FONT;
  185.     } else if (strcmpi(tmp, Stock_Fonts[3]) == 0) {
  186.     stock_font = OEM_FIXED_FONT;
  187.     } else if (strcmpi(tmp, Stock_Fonts[4]) == 0) {
  188.     stock_font = SYSTEM_FONT;
  189.     }
  190.     if (stock_font != -1) {
  191.     id = (void*)GetStockObject(stock_font);
  192.     return true;
  193.     }
  194.     return false;
  195. }
  196.  
  197. void Font::GetFontByName (const char* name) {
  198.     if (!rep->IsStockFont(name)) {
  199.     rep->MakeNewFont(name);
  200.     }
  201. }
  202.  
  203. Font::~Font () {
  204.     Unref(rep);
  205. }
  206.  
  207. void FontRep::GetFontString (char** fontstring) {
  208.     FILE* source;
  209.     char buf[FONTSTRINGSIZE];
  210.     char str[FONTSTRINGSIZE];
  211.     char *file, *ptr;
  212.     int num_substrs = 0;
  213.     char* substrs[13];
  214.     boolean result;
  215.  
  216.     (*fontstring)[0] = '\0';
  217.  
  218.     //
  219.     //   Der String mit den Wildcards wird in diejenigen Teilstrings
  220.     //   aufgespalten, die im eigentlichen Fontstring enthalten sein müssen.
  221.     //
  222.  
  223.     strcpy(str, name);
  224.     if ((substrs[num_substrs] = strtok(str, "*\0")) != NULL) {
  225.     num_substrs++;
  226.     }
  227.     while ((substrs[num_substrs] = strtok(NULL, "*\0")) != NULL) {
  228.     num_substrs++;
  229.     }
  230.  
  231.     //
  232.     // Es wird Zeile für Zeile der Fontdatenbank gelesen und auf Vorkommen
  233.     // der Teilstrings untersucht. Die erste Zeile, die alle Teilstrings
  234.     // enthält, ist der eigentliche Fontstring.
  235.     //
  236.  
  237.  
  238.     file = searchpath("fonts.dir");
  239.     if (file == 0) {
  240.         return;
  241.     }
  242.  
  243.     source = fopen(file, "r");
  244.  
  245.     while (!feof(source)) {
  246.     fgets(buf, FONTSTRINGSIZE, source);
  247.     result = true;
  248.     ptr = buf;
  249.     for (int i = 0; i < num_substrs; i++) {
  250.         if ((ptr = strstr(ptr, substrs[i])) == NULL) {
  251.         result = false;
  252.         break;
  253.         }
  254.         ptr++;
  255.     }
  256.     if (result) {
  257.         strcpy((*fontstring), buf);
  258.         break;
  259.     }
  260.     }
  261.     fclose(source);
  262. }
  263.  
  264. unsigned char FontRep::GetLogFontCharSet () {
  265.     char tmp[LF_FACESIZE];
  266.     BYTE char_set = ANSI_CHARSET;
  267.  
  268.     strcpy(tmp, typeface);
  269.     if (strcmpi(typeface, "terminal") == 0 ||
  270.         strcmpi(typeface, "modern") == 0 ||
  271.         strcmpi(typeface, "roman") == 0 ||
  272.         strcmpi(typeface, "script") == 0 ) {
  273.         char_set = OEM_CHARSET;
  274.     }
  275.     return char_set;
  276. }
  277.  
  278.  
  279. void FontRep::GetLogFontTypeFace (char* ptr) {
  280.     ifstream source;
  281.     char buf[128];
  282.     char *p, *file;
  283.  
  284.     strcpy(typeface, ptr);
  285.  
  286.     if ((file = searchpath("fonts.tfc")) == 0) {
  287.         return;
  288.     }
  289.     source.open(file, ios::nocreate);
  290.     while (!source.eof()) {
  291.     source.getline(buf, 128);
  292.     if (strstr(buf, typeface)) {
  293.         p = strchr(buf, '@') + 1;
  294.         strcpy(typeface, p);
  295.         source.close();
  296.         return;
  297.     }
  298.     }
  299.     source.close();
  300. }
  301.  
  302. boolean FontRep::GetLogFont (void* logfont) {
  303.     char* buffer = new char[FONTSTRINGSIZE];
  304.     char* ptr;
  305.     int value;
  306.     LPLOGFONT lf = (LPLOGFONT)logfont;
  307.  
  308.     strcpy(buffer, name);
  309.     GetFontString(&buffer);
  310.     if (buffer[0] == '\0') {
  311.     return false;
  312.     }
  313.  
  314.                         /* Foundry */
  315.     if ((ptr = strtok(buffer, "-")) != NULL);
  316.  
  317.                         /* Font Family */
  318.  
  319.     if ((ptr = strtok(NULL, "-")) != NULL) {
  320.     GetLogFontTypeFace(ptr);
  321.     for (int i = 0; i <= strlen(typeface); i++) {
  322.         lf->lfFaceName[i] = typeface[i];
  323.     }
  324.     }
  325.     lf->lfCharSet = GetLogFontCharSet();
  326.  
  327.                         /* Weight */
  328.     lf->lfWeight = 400;
  329.     if ((ptr = strtok(NULL, "-")) != NULL) {
  330.     if (!strcmpi(ptr, "bold")) {
  331.         lf->lfWeight = 700;
  332.     }
  333.     }
  334.  
  335.                         /* Slant */
  336.     lf->lfItalic = 0;
  337.     if ((ptr = strtok(NULL, "-")) != NULL) {
  338.     if (!strcmpi(ptr, "i") || !strcmpi(ptr, "o")) {
  339.         lf->lfItalic = 1;
  340.     }
  341.     }
  342.  
  343.                         /* Set Width */
  344.     if ((ptr = strtok(NULL, "-")) != NULL);
  345.  
  346.  
  347.                         /* Pixels */
  348.     lf->lfHeight = 0;
  349.     if (((ptr = strtok(NULL, "-")) != NULL) && (value = atoi(ptr))) {
  350.     lf->lfHeight = value;
  351.     }
  352.  
  353.                         /* Points */
  354.     if ((ptr = strtok(NULL, "-")) != NULL);
  355.  
  356.                         /* Hor. Resolution */
  357.     if ((ptr = strtok(NULL, "-")) != NULL);
  358.  
  359.                         /* Vert. Resolution */
  360.     if ((ptr = strtok(NULL, "-")) != NULL);
  361.  
  362.                         /* Spacing */
  363.     lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  364.     if ((ptr = strtok(NULL, "-")) != NULL) {
  365.     if (!strcmpi(ptr, "m")) {
  366.         lf->lfPitchAndFamily |= FIXED_PITCH;
  367.     }
  368.     if (!strcmpi(ptr, "p")) {
  369.         lf->lfPitchAndFamily |= VARIABLE_PITCH;
  370.     }
  371.     }
  372.  
  373.                         /* Width */
  374.     lf->lfWidth = 0;
  375.     if ((ptr = strtok(NULL, "-")) != NULL);
  376.  
  377.  
  378.                         /* Character Set */
  379.     if ((ptr = strtok(NULL, "-\n")) != NULL);
  380.  
  381.                         /* Defaults */
  382.     lf->lfEscapement = 0;
  383.     lf->lfOrientation = 0;
  384.     lf->lfUnderline = 0;
  385.     lf->lfStrikeOut = 0;
  386.     lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
  387.     lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
  388.     lf->lfQuality = DEFAULT_QUALITY;
  389.  
  390.     delete buffer;
  391.     return true;
  392. }
  393.  
  394. void FontRep::GetFontAlias (const char* f) {
  395.     ifstream source;
  396.     char buf[FONTSTRINGSIZE];
  397.     char *ptr, *file;
  398.  
  399.     if ((file = searchpath("fonts.ali")) == 0) {
  400.         return;
  401.     }
  402.     source.open(file, ios::nocreate);
  403.     while (!source.eof()) {
  404.     source.getline(buf, FONTSTRINGSIZE);
  405.     if (strstr(buf, f)) {
  406.         ptr = &buf[strlen(f)];
  407.         while (*ptr == ' ') {
  408.         ptr++;
  409.         }
  410.         strcpy(name, ptr);
  411.         return;
  412.     }
  413.     }
  414.     source.close();
  415. }
  416.  
  417. boolean FontRep::GetFontResource (char** font_resource) {
  418.     ifstream source;
  419.     char buf[128];
  420.     char *ptr, *file;
  421.  
  422.     if ((file = searchpath("fonts.rsc")) == 0) {
  423.         return false;
  424.     }
  425.     source.open(file, ios::nocreate);
  426.     while (!source.eof()) {
  427.     source.getline(buf, 128);
  428.     if (strstr(buf, typeface)) {
  429.         ptr = strchr(buf, '@') + 1;
  430.         strcpy(*font_resource, ptr);
  431.         source.close();
  432.         return true;
  433.     }
  434.     }
  435.     source.close();
  436.     return false;
  437. }
  438.  
  439. void FontRep::MakeNewFont (const char* font) {
  440.     char* font_res = new char[13];
  441.     LOGFONT logFont;
  442.  
  443.     id = (void*)GetStockObject(SYSTEM_FONT);
  444.     strcpy(name, font);
  445.     GetFontAlias(font);
  446.     if (GetLogFont(&logFont)) {
  447.     if (GetFontResource(&font_res)) {
  448.         if (AddFontResource(font_res)) {
  449.         id = (void*)CreateFontIndirect(&logFont);
  450.         }
  451.     }
  452.     }
  453.     delete font_res;
  454. }
  455.  
  456. int Font::Baseline () {
  457.     TEXTMETRIC metrics;
  458.     int result = 0;
  459.     HDC hDC = _world->hdc();
  460.  
  461.     HFONT holdFont = nil;
  462.     if (Valid()) {
  463.     holdFont = SelectObject(hDC, (HFONT)Id());
  464.     }
  465.     if (GetTextMetrics(hDC, (LPTEXTMETRIC)&metrics)) {
  466.     result = metrics.tmDescent;
  467.     }
  468.     if (holdFont != nil) {
  469.     SelectObject(hDC, holdFont);
  470.     }
  471.     return result;
  472. }
  473.  
  474. int Font::Width (const char* s) {
  475.     return Width(s, strlen(s));
  476. }
  477.  
  478. int Font::Width (const char* s, int len) {
  479.     int result, length;
  480.     HDC hDC = _world->hdc();
  481.  
  482.     length = strlen(s);
  483.     if (length > len) {
  484.     length = len;
  485.     }
  486.     HFONT holdFont;
  487.     holdFont = SelectObject(hDC, (HFONT)Id());
  488.     result = GetTextExtent(hDC, (LPSTR)s, length);
  489.     SelectObject(hDC, holdFont);
  490.     return result;
  491. }
  492.  
  493. int Font::Height () {
  494.     TEXTMETRIC tm;
  495.     int result;
  496.     HDC hDC = _world->hdc();
  497.  
  498.     HFONT holdFont = SelectObject(hDC, (HFONT)rep->id);
  499.     GetTextMetrics(hDC, &tm);
  500.     result = tm.tmHeight;
  501.     SelectObject(hDC, holdFont);
  502.     return result;
  503. }
  504.  
  505. int Font::Index (const char* s, int len, int offset, boolean between) {
  506.     const char* p;
  507.     int n, w;
  508.     int coff, cw;
  509.     HDC hDC = _world->hdc();
  510.  
  511.     HFONT holdFont = nil;
  512.     holdFont = SelectObject(hDC, (HFONT)Id());
  513.  
  514.     if (offset < 0 || *s == '\0' || len == 0) {
  515.     return 0;
  516.     }
  517.     w = 0;
  518.     for (p = s, n = 0; *p != '\0' && n < len; ++p, ++n) {
  519.     w += GetTextExtent(hDC, (LPSTR)s, n+1);
  520.     cw = GetTextExtent(hDC, (LPSTR)p, 1);
  521. //      w += cw;
  522.     if (w > offset) {
  523.         break;
  524.     }
  525.     coff = offset - w;
  526.     }
  527.     if (between && coff > cw/2) {   // der Index, der am nächsten zu offset
  528.       ++n;
  529.     }
  530.  
  531.     SelectObject(hDC, holdFont);
  532.     return min(++n, len);
  533. }
  534.  
  535. boolean Font::FixedWidth () {
  536.     LOGFONT logFont;
  537.  
  538.     if (Valid()) {
  539.     GetObject((HFONT)Id(), sizeof(logFont), (LPSTR)&logFont);
  540.     if (logFont.lfPitchAndFamily & FIXED_PITCH) {
  541.         return true;
  542.     }
  543.     }
  544.     return false;
  545. }
  546.  
  547. /*
  548.  **************************  class Pattern  ***********************
  549.  */
  550. /*
  551. int _xpos = 0;
  552. int _ypos = 400;
  553.  
  554. void _DisplayBitmap(void* map, int width, int height) {
  555.  
  556.     WNDCLASS wc;
  557.  
  558.     wc.style = NULL;
  559.     wc.lpfnWndProc = DefWindowProc;
  560.     wc.cbClsExtra = 0;
  561.     wc.cbWndExtra = 0;
  562.     wc.hInstance = _world->hinstance();
  563.     wc.lpszMenuName = NULL;
  564.     wc.lpszClassName = "iii";
  565.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  566.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  567.     HBRUSH bg = CreateSolidBrush(RGB(0, 0, 255));
  568.     wc.hbrBackground = bg;
  569.  
  570.     RegisterClass(&wc);
  571.  
  572.     HWND hWnd = CreateWindow(
  573.         "iii",
  574.         "Bitmap",
  575.         WS_BORDER,
  576.         _xpos,
  577.         _ypos,
  578.         50,
  579.         80,
  580.         NULL,
  581.         NULL,
  582.         _world->hinstance(),
  583.         NULL
  584.        );
  585.  
  586.      _xpos += 50;
  587.      if (_xpos >= 600) {
  588.      _xpos = 0;
  589.      _ypos += 80;
  590.      }
  591.      if (hWnd) {
  592.     void* c;
  593.     c = (void*)hWnd;
  594.     ShowWindow((HWND)c, SW_SHOW);
  595.     }
  596.  
  597.     HDC hDC = GetDC(hWnd);
  598.     HDC hMemDC = CreateCompatibleDC(hDC);
  599.     HBITMAP holdBitmap = SelectObject(hMemDC, (HBITMAP)map);
  600.     BitBlt(hDC, 5, 5, width, height, hMemDC, 0, 0, SRCCOPY);
  601.     SelectObject(hMemDC, holdBitamp);
  602.     DeleteDC(hMemDC);
  603.     ReleaseDC(hWnd, hDC);
  604. }
  605.  
  606. */
  607.  
  608. #ifdef bitmap_h
  609.  
  610. HBITMAP GetInvertedBitmap (Bitmap* b) {
  611.     HBITMAP hBitmap = CreateBitmap(b->Width(), b->Height(), 1, 1, NULL);
  612.     HDC hMemDC = CreateCompatibleDC(_world->hdc());
  613.     HDC hMemDC1 = CreateCompatibleDC(_world->hdc());
  614.     HBITMAP holdBitmap = SelectObject(hMemDC, (HBITMAP)b->Map());
  615.     HBITMAP holdBitmap1 = SelectObject(hMemDC1, hBitmap);
  616.     PatBlt(hMemDC1, 0, 0, b->Width(), b->Height(), BLACKNESS);
  617.     BitBlt(hMemDC1, 0, 0, b->Width(), b->Height(), hMemDC, 0, 0, SRCINVERT);
  618.     SelectObject(hMemDC1, holdBitmap1);
  619.     SelectObject(hMemDC, holdBitmap1);
  620.     DeleteDC(hMemDC1);
  621.     DeleteDC(hMemDC);
  622.     return hBitmap;
  623. }
  624.  
  625. Pattern::Pattern (Bitmap* b) {
  626.     HBITMAP hBitmap = GetInvertedBitmap(b);
  627.     info = (void*)CreatePatternBrush(hBitmap);
  628.     DeleteObject(hBitmap);
  629. }
  630.  
  631. Pattern::Pattern (int p[patternHeight]) {
  632.     int newp[patternHeight];
  633.     for (int i = 0; i < patternHeight; i++) {
  634.     newp[i] = ~p[i];
  635.     }
  636.     HBITMAP hBitmap = CreateBitmap(8, 8, 1, 1, (LPSTR)newp);
  637.     info = (void*)CreatePatternBrush(hBitmap);
  638.     DeleteObject(hBitmap);
  639. }
  640.  
  641. Pattern::Pattern (int dither) {
  642.     int i, seed;
  643.     short int r[8];
  644.  
  645.     seed = dither;
  646.     for (i = 0; i < 4; i++) {
  647.     r[i] = (seed & 0xf000) >> 12;
  648.     r[i] |= r[i] << 4;
  649.     r[i] |= r[i] << 8;
  650.     seed <<= 4;
  651.     r[i] = ~r[i];
  652.     r[i+4] = r[i];
  653.     }
  654.     HBITMAP hBitmap = CreateBitmap(8, 8, 1, 1, (LPSTR)r);
  655.     info = (void*)CreatePatternBrush(hBitmap);
  656.     DeleteObject(hBitmap);
  657. }
  658.  
  659. Pattern::~Pattern () {
  660.     if (info != nil) {
  661.     DeleteObject((HBRUSH)info);
  662.     }
  663. }
  664.  
  665. #endif
  666.  
  667.